package com.onpositive.wiki3.db.catmodel.matches.classify;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Set;

import com.carrotsearch.hppc.IntOpenHashSet;
import com.onpositive.wiki3.db.IWikiDB;
import com.onpositive.wiki3.db.catmodel.Categories;
import com.onpositive.wiki3.db.catmodel.Category;

public class RelationStore {

	protected HashMap<String, Categories> relations = new HashMap<String, Categories>();
	protected IWikiDB db;
	private String path;

	public RelationStore(IWikiDB db) {
		super();
		this.db = db;
		path = db.getPath();
		try {
			log=new PrintStream(new BufferedOutputStream(new FileOutputStream(db.getPath()+"/rs.log")));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public int itemCount(){
		IntOpenHashSet os=new IntOpenHashSet();
		for (Categories m:relations.values()){
			for (Category c:m){
				os.add(c.id());
			}
		}
		return os.size();		
	}
	PrintStream log;

	public Categories get(String relation) {
		Categories categories = relations.get(relation);
		if (categories == null) {
			File file = new File(getRoot(), relation + ".rel");
			if (file.exists()) {
				categories = new Categories(db, file, false);
			} else {
				categories = new Categories(db);
			}
			relations.put(relation, categories);
		}
		return categories;
	}

	public void recordRelation(String relation, Category parent, Category child) {
		
		Categories categories = get(relation);
		Category pc = categories.get(parent.id());
		Category cc = categories.get(child.id());
		if (pc!=null&&cc!=null&&pc.hasChild(cc.id())){
			return;
		}
		System.out.println(parent+"->"+child);
		log.println(parent+"->"+child);
		if (!allP(pc, cc)){
			categories.registerChild(parent.id(), child.id());
		}
		else{
			System.out.println("Parent:"+parent+":"+child);
		}
	}
	
	

	protected boolean allP(Category pc, Category cc) {
		if (pc==null||cc==null){
			return false;
		}
		return pc.hasParent(cc, Integer.MAX_VALUE);
	}

	public void removeRelation(String relation, Category parent, Category child) {
		Categories categories = get(relation);
		categories.unregisterChild(parent.id(), child.id());
	}

	public void register(String relation, Category obj) {
		Categories categories = get(relation);
		categories.getOrCreate(obj.id());
	}

	public void unregister(String relation, Category obj) {
		Categories categories = get(relation);
		categories.removeCategory(obj.id());
	}

	public void clear() {
		relations.clear();
	}

	public void save() throws IOException {
		File f = getRoot();
		f.mkdirs();
		for (String s : relations.keySet()) {
			File m = new File(f, s + ".rel");
			relations.get(s).write(m);
		}
	}

	protected File getRoot() {
		return new File(path, "relations");
	}

	public Set<Category> getAll(String isA, Category z) {
		Categories m=get(isA);
		Category category = m.get(z.id());
		if (category==null){
			return Collections.emptySet();
		}
		Set<Category> allParents = category.getAllParents();
		allParents.add(category);
		return allParents;
	}
}
